import cv2
import numpy as np
def detectAndDescribe(image):
    gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    sift=cv2.SIFT_create()
    kp,des=sift.detectAndCompute(gray,None)
    image=cv2.drawKeypoints(image,kp,image)
    return image,kp,des
img1=cv2.imread("left_02.png")
img2=cv2.imread("right_02.png")
imgA=img1.copy()
imgB=img2.copy()
imgA,kpA,desA=detectAndDescribe(imgA)
imgB,kpB,desB=detectAndDescribe(imgB)
input=np.hstack((imgA,imgB))
cv2.imshow('Keypoints_Input',input)


matcher=cv2.BFMatcher(cv2.NORM_L2)
rawMatches=matcher.knnMatch(desA,desB,2)
ratio=0.7
matches=[[m] for m,n in rawMatches if m.distance<ratio*n.distance]
out=cv2.drawMatchesKnn(imgA,kpA,imgB,kpB,matches,None)
cv2.imshow('drawMatches',out)



def get_homo(kpA,kpB,matches):
    reprojThresh=4.0
    kpsA=np.float32([kp.pt for kp in kpA])
    kpsB=np.float32([kp.pt for kp in kpB])
    ptsA=np.float32([kpsA[m[0].queryIdx]for m in matches])
    ptsB = np.float32([kpsB[m[0].trainIdx] for m in matches])
    (H, status) = cv2.findHomography(ptsB, ptsA, cv2.RANSAC, reprojThresh)
    return H
if len(matches) > 4:
    H = get_homo(kpA, kpB, matches)
    result = cv2.warpPerspective(img2, H, (img1.shape[1] + img2.shape[1], img2.shape[0]))
    cv2.imshow('Right', result)
    result[0:img1.shape[0], 0:img1.shape[1]] = img1
    cv2.imshow('Result', result)
cv2.waitKey()
cv2.destroyAllWindows()
